﻿using Elsa.ApprovalFlow.Entities;
using Elsa.Extensions;
using Elsa.Workflows;
using Elsa.Workflows.Activities;
using Elsa.Workflows.Management.Activities.SetOutput;
using Elsa.Workflows.Models;

namespace Elsa.ApprovalFlow.Workflows;

public class LeaveApprovalWorkflow : WorkflowBase
{
    protected override void Build(IWorkflowBuilder builder)
    {
        // var leaveRequestInput = builder.WithInput<LeaveRequest>("leaveRequest");
        // 定义输出
        var isApproved = builder.WithVariable<bool>();
        var approvalComments = builder.WithVariable<string>();
        var currentApproverRole = builder.WithVariable<string>();
        var leaveRequest = builder.WithVariable<LeaveRequest>();
        var leaveRole = builder.WithVariable<string>();


        // 工作流定义
        builder.Root = new Sequence
        {
            Activities =
            {
                // 设置当前审批角色
                new SetVariable
                {
                    Variable = leaveRole,
                    Value = new(context => GetApprovalRole(context.GetInput<LeaveRequest>("leaveRequest")!))
                },
                new SetVariable
                {
                    Variable = leaveRequest,
                    Value = new(context => context.GetInput<LeaveRequest>("leaveRequest")!)
                },
                
                // 1天内自动审批
                new If(context => leaveRequest.Get(context)!.TotalDays <= 1)
                {
                    Then = new Sequence
                    {
                        Activities =
                        {
                            new ApproveRequest
                            {
                                LeaveRequest = new(context => leaveRequest.Get(context)!)
                            }
                        }
                    },
                    Else = new If(context => leaveRequest.Get(context)!.TotalDays <= 3)
                    {
                        Then = new Sequence
                        {
                            Activities =
                            {
                                // 3天需要部门经理审批
                                new SetApproverRole()
                                {
                                    LeaveRequest = new(context => leaveRequest.Get(context)!),
                                    Role = new Input<string>(() => "DepartmentManager")
                                },
                                new WaitForApproval()
                                {
                                    LeaveRequest = new(context => leaveRequest.Get(context)!),
                                    OutputLeaveRequest = new(leaveRequest),
                                },
                                new If(context => leaveRequest.Get(context)!.Status == "Approved")
                                {
                                    Then = new ApproveRequest(){
                                        LeaveRequest = new(context => leaveRequest.Get(context)!),
                                    },
                                    Else = new RejectRequest(){
                                        LeaveRequest = new(context => leaveRequest.Get(context)!),
                                    }
                                }
                            }
                        },
                        Else = new If(context => leaveRequest.Get(context)!.TotalDays <= 10)
                        {
                            Then = new Sequence
                            {
                                Activities =
                                {
                                    // 10天需要HR总监审批
                                    new SetApproverRole()
                                    {
                                        LeaveRequest = new(context => leaveRequest.Get(context)!),
                                        Role = new Input<string>(() => "HRDirector")
                                    },
                                    new WaitForApproval()
                                    {
                                        LeaveRequest = new(context => leaveRequest.Get(context)!),
                                        OutputLeaveRequest = new(leaveRequest),
                                    },
                                    new If(context => leaveRequest.Get(context)!.Status == "Approved")
                                    {
                                        Then = new ApproveRequest(){
                                            LeaveRequest = new(context => leaveRequest.Get(context)!),
                                        },
                                        Else = new RejectRequest(){
                                            LeaveRequest = new(context => leaveRequest.Get(context)!),
                                        }
                                    }
                                }
                            },
                            Else = new Sequence
                            {
                                Activities =
                                {
                                    // 其他天数需要直接主管审批                                
                                    new SetApproverRole()
                                    {
                                        LeaveRequest = new(context => leaveRequest.Get(context)!),
                                        Role = new Input<string>(() => "Supervisor")
                                    },
                                    new WaitForApproval()
                                    {
                                        LeaveRequest = new(context => leaveRequest.Get(context)!),
                                        OutputLeaveRequest = new(leaveRequest),
                                    },
                                    new If(context => leaveRequest.Get(context)!.Status == "Approved")
                                    {
                                        Then = new ApproveRequest()
                                        {
                                            LeaveRequest = new(context => leaveRequest.Get(context)!),
                                        },
                                        Else = new RejectRequest()
                                        {
                                            LeaveRequest = new(context => leaveRequest.Get(context)!),
                                        }
                                    }
                                }
                            }
                        }
                    }
                },

                new SetOutput
                {
                    OutputName = new Input<string>("leaveRequest"),
                    OutputValue = new(leaveRequest)
                }
                // 持久化结果
                //new PersistLeaveRequest(leaveRequest)
            }
        };
    }

    private string GetApprovalRole(LeaveRequest leaveRequest)
    {
        return leaveRequest.TotalDays switch
        {
            <= 1 => "AutoApproval",
            >= 3 and < 10 => "DepartmentManager",
            >= 10 => "HRDirector",
            _ => "Supervisor"
        };
    }
}

// 自定义活动：设置审批人角色
public class SetApproverRole : Activity
{
    public Input<LeaveRequest> LeaveRequest { get; set; } = default!;
    public Input<string> Role { get; set; } = default!;

    protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
    {
        var request = LeaveRequest.Get(context);
        request.CurrentApprovalRole = Role.Get(context);

        // 完成活动并传递结果
        await context.CompleteActivityAsync(new Dictionary<string, object>
        {
            ["leaveRequest"] = request
        });
    }
}

// 自定义活动：等待审批
public class WaitForApproval : Activity
{
    public Input<LeaveRequest> LeaveRequest { get; set; } = default!;
    public Output<LeaveRequest> OutputLeaveRequest { get; set; } = default!;

    protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
    {
        var request = LeaveRequest.Get(context);
        Console.WriteLine($"等待 {request.CurrentApprovalRole} 审批请假申请 {request.Id}");

        // 创建书签参数
        var bookmarkArgs = new CreateBookmarkArgs
        {
            BookmarkName = $"leave-approval:{request.Id}:{request.CurrentApprovalRole}",
            Callback = OnResume,
            AutoBurn = true,
            IncludeActivityInstanceId = true,
            Metadata = new Dictionary<string, string>
            {
                ["RequestId"] = request.Id,
                ["ApprovalRole"] = request.CurrentApprovalRole,
                ["Description"] = $"等待 {request.CurrentApprovalRole} 审批请假申请"
            }
        };

        // 创建书签
        context.CreateBookmark(bookmarkArgs);

        OutputLeaveRequest.Set(context, request);
    }

    private async ValueTask OnResume(ActivityExecutionContext context)
    {
        // 获取输入数据
        var approved = context.GetWorkflowInput<bool>();
        var comments = context.GetWorkflowInput<string>();

        // 获取请假请求
        var request = LeaveRequest.Get(context);

        // 更新请求状态
        request.Status = approved ? "Approved" : "Rejected";
        request.Comments = comments;

        // 完成活动并传递结果
        await context.CompleteActivityAsync(new Dictionary<string, object>
        {
            ["leaveRequest"] = request
        });
    }

    // 审批输入模型
    public record ApprovalInputModel(bool IsApproved, string Comments, string ApproverId);
}

public class ApproveRequest : Activity
{
    public Input<LeaveRequest> LeaveRequest { get; set; } = default!;

    protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
    {
        var request = LeaveRequest.Get(context);
        request.Status = "Approved";
        request.Comments = "自动批准";
        request.CurrentApprovalRole = "AutoApproval";

        // 完成活动并传递结果
        await context.CompleteActivityAsync(new Dictionary<string, object>
        {
            ["leaveRequest"] = request
        });
    }
}

// 自定义活动：拒绝请求
public class RejectRequest : Activity
{
    public Input<LeaveRequest> LeaveRequest { get; set; } = default!;

    protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
    {
        var request = LeaveRequest.Get(context);
        request.Status = "Rejected";
        // 完成活动并传递结果
        await context.CompleteActivityAsync(new Dictionary<string, object>
        {
            ["leaveRequest"] = request
        });
    }
}

// 自定义活动：持久化请假请求
public class PersistLeaveRequest : Activity
{
    public Input<LeaveRequest> LeaveRequest { get; set; } = default!;

    protected override void Execute(ActivityExecutionContext context)
    {
        var request = LeaveRequest.Get(context);
        request.WorkflowInstanceId = context.WorkflowExecutionContext.Id;

        // 这里实际应该调用持久化服务
        Console.WriteLine($"持久化请假请求: {System.Text.Json.JsonSerializer.Serialize(request)}");
    }
}